package vns.client.view;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.tools.ant.types.Assertions.EnabledAssertion;

import vns.client.helper.Helper;
import vns.client.helper.NumericTextBox;
import vns.client.presenter.ObjectPresenter;
import vns.shared.ObjectDTO;
import vns.shared.ObjectPropertyDTO;
import vns.shared.ObjectPropertyTypeDTO;
import vns.shared.ObjectTypeDTO;

import com.google.appengine.api.datastore.KeyFactory;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.datepicker.client.DateBox;

public class ObjectUI extends Composite implements ObjectPresenter.Display{

	private List<String> listStringColumn = new ArrayList<String>();
	private static ObjectUIUiBinder uiBinder = GWT
			.create(ObjectUIUiBinder.class);
	private static int rowSelectedID=-1;
	private static int rowEditingID=-1;

	private List<ObjectDTO> listRow = new ArrayList<ObjectDTO>();
	private List<ObjectPropertyDTO> listProperty = new ArrayList<ObjectPropertyDTO>();
	private ObjectTypeDTO currentObjectTypeDTO = new ObjectTypeDTO();

	@UiField
	FlexTable flexTable;
	@UiField
	Button btAdd;
	@UiField
	Button btEdit;
	@UiField
	Button btDel;
	@UiField
	Button btUpdate;
	@UiField
	HTMLPanel htmlpanelObjectDetail;

	interface ObjectUIUiBinder extends UiBinder<Widget, ObjectUI> {
	}

	/*
	 * Constructor
	 */
	public ObjectUI() {
		initWidget(uiBinder.createAndBindUi(this));
		bind();
	}

	private void bind() {

		flexTable.setBorderWidth(1);
		flexTable.setCellPadding(2);
		flexTable.setCellSpacing(0);

		/*
		 * FlexTable Even
		 */
		flexTable.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				getClickedRow(event);

			}
		});
		rowEditingID = -1;
	}
	/***************************************************************************/
	public void renderClickedRow() {
		if (rowSelectedID > 0) {
			HTMLTable.RowFormatter rf = flexTable.getRowFormatter();
			rf.addStyleName(rowSelectedID, "vnsClickedRow");
		}
	}

	public void unrenderClickedRow() {
		if (rowSelectedID > 0) {
			HTMLTable.RowFormatter rf = flexTable.getRowFormatter();
			rf.removeStyleName(rowSelectedID, "vnsClickedRow");
		}
	}

	public int getClickedRow(ClickEvent event) {
		int selectedRow = -1;
		HTMLTable.Cell cell = flexTable
				.getCellForEvent(event);

		if (cell != null) {
			if (cell.getCellIndex() >= 0) {
				selectedRow = cell.getRowIndex();
			}
			swapClickedRow(selectedRow, cell.getCellIndex());
		}
		
		return selectedRow;
	}

	private void swapClickedRow(int rowNow, int cellindex) {
		if (rowNow != rowSelectedID && rowNow>0){
			unrenderClickedRow();
			setRowEnable(rowSelectedID, false);
			rowSelectedID = rowNow;
			
			renderClickedRow();
			setRowEnable(rowSelectedID, true);
//			Window.alert("Hàng chọn bây giờ: "
//					+ Integer.toString(rowSelectedID));
		} else if(rowNow == rowSelectedID && rowNow > 0){
			if(cellindex==0){
				unrenderClickedRow();
				setRowEnable(rowSelectedID, false);
				rowSelectedID = -1;
			}
		}else if(rowNow == -1){
			unrenderClickedRow();
			setRowEnable(rowSelectedID, false);
			rowSelectedID = -1;
		}
	}

	/*
	 * Set Row Enable
	 */
	private void setRowEnable(int row, boolean value, boolean order) {
		if (row <= flexTable.getRowCount() - 1 && row > 0) {
			CheckBox orderCheckBox = (CheckBox) flexTable.getWidget(row, 0);
			orderCheckBox.setValue(value);
			orderCheckBox.setEnabled(order);
		}
	}
	private void setRowEnable(int row, boolean value) {
		setRowEnable(row, value, true);
	}
	/*
	 * Get Order CheckBox
	 */
	private CheckBox OrderCheckBox(int row, boolean value, boolean enable) {
		final CheckBox cb = new CheckBox();
		cb.setValue(value);
		cb.setEnabled(enable);
		return cb;
	}
	/*************************************************************************/
	/*
	 * Init
	 */

	private void initTableFirst() {
		flexTable.removeAllRows();

		/*
		 * Tên các cột
		 */
		listStringColumn.clear();
		listStringColumn.add("");						//order
		for(ObjectPropertyDTO o : this.listProperty){
			if(o.getList())
				listStringColumn.add(o.getName());
		}

		int i = 0;
		for (final String columnName : listStringColumn) {
			flexTable.setHTML(0, i, "<center><b>" + columnName
					+ "</b></center>");
			i++;
		}
	}
	/*
	 * Remove selected Row
	 */
	private void removeRow() {
		if (rowSelectedID > 0 && rowSelectedID < flexTable.getRowCount() ){
			flexTable.removeRow(rowSelectedID);
			int remvIndex = Helper.getIndexByRow(rowSelectedID, listRow.size());
			if(remvIndex!=-1){
				listRow.remove(remvIndex);
			}
			rowSelectedID = -1;
		} else
			Window.alert("Chọn hàng cần xóa!");
	}
	/*
	 * Update all rows
	 */
	private void updateRow() {
	}
	
	private void editRow() {
		if(rowSelectedID>0 && rowSelectedID<flexTable.getRowCount()){
			rowEditingID = rowSelectedID;
		}
	}
	
	/*
	 * Event
	 */
	
	@UiHandler("btAdd")
	void onBtAddClick(ClickEvent event) {
//		addRow();
	}
	
	@UiHandler("btDel")
	void onBtDelClick(ClickEvent event) {
		removeRow();
	}
	
	@UiHandler("btUpdate")
	void onBtUpdateClick(ClickEvent event) {
		updateRow();
	}
	
	@UiHandler("btEdit")
	void onBtEditClick(ClickEvent event) {
		editRow();
	}
	
	/***************************************************************/

	/*
	 * Overide Display
	 * 
	 */

	@Override
	public ArrayList<ObjectDTO> getListRow() {
		return (ArrayList<ObjectDTO>) listRow;
	}

	@Override
	public boolean setListRow(List<ObjectDTO> listRow) {
		this.listRow = listRow;
		return true;
	}
	
	@Override
	public void render() {
		rowSelectedID = -1;
		initTableFirst();
		for (final ObjectDTO o : this.listRow) {
			addRow(o.getListProperty());
		}
	}
	private void addRow(List<ObjectPropertyDTO> list) {
		int row = flexTable.getRowCount();
		CheckBox cb = OrderCheckBox(row, false, true);
		flexTable.setWidget(row, 0, cb);
		int i = 1;
		for(ObjectPropertyDTO op : list){
			if(op.getList())
				flexTable.setText(row, i, getValueFromPType(i,op.getValue(),op.getlistObjectRelated()));
			i++;
		}
	}
	private String getValueFromPType(int column, String value, List<ObjectDTO> listORelatedDTO) {
//		Window.alert("ObjectUI|getValueFromPType " + 
//				this.listProperty.get(cloumn-1).getOptypename());
		String type = this.listProperty.get(column-1).getOptypename();
		if(type.equalsIgnoreCase("string")){
		}else if(type.equalsIgnoreCase("integer") ||
				type.equalsIgnoreCase("float") ||
				type.equalsIgnoreCase("double") ||
				type.equalsIgnoreCase("long")
				){
		}else if(type.equalsIgnoreCase("boolean")){
		}else if(type.equalsIgnoreCase("password")){
		}else if(type.equalsIgnoreCase("date") ||
				type.equalsIgnoreCase("datetime")
				){
		}else if(type.equalsIgnoreCase("key")){
			for(ObjectDTO oRelatedDTO : listORelatedDTO){
				String oRelatedDTOKey = KeyFactory.keyToString(oRelatedDTO.getId());
				if(oRelatedDTOKey.equals(value))
					value=oRelatedDTO.getMain();
			}
		}
		return value;
	}
	@Override
	public Widget asWidget(){
		return this;
	}

	@Override
	public HTMLPanel getHTMLPanelDetail() {
		return htmlpanelObjectDetail;
	}

	@Override
	public ObjectDTO getCurrentObjectDTO() {
		if(rowEditingID>0 && rowEditingID<flexTable.getRowCount()){
		int index = Helper.getIndexByRow(rowEditingID, this.listRow.size());
		return listRow.get(index);
		}else{
			return null;
		}
	}

	@Override
	public void setListProperty(List<ObjectPropertyDTO> listProperty) {
		this.listProperty = listProperty;
	}

	@Override
	public List<ObjectPropertyDTO> getListProperty() {
		return listProperty;
	}

	@Override
	public void setCurrentObjectTypeDTO(ObjectTypeDTO currentObjectTypeDTO) {
		this.currentObjectTypeDTO = currentObjectTypeDTO;
	}

	@Override
	public ObjectTypeDTO getCurrentObjectTypeDTO() {
		return currentObjectTypeDTO;
	}

	@Override
	public Button getAddButton() {
		return btAdd;
	}

	@Override
	public Button getEditButton() {
		return btEdit;
	}

	@Override
	public Button getUpdateButton() {
		return btUpdate;
	}


}
